package com.wangwenjun.concurrency.chapter14.cyclicbarrier;

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @Package: com.wangwenjun.concurrency.chapter14
 * @ClassName: UseCyclicBarrier
 * @Author: lujieni
 * @Description: 使用UseCyclicBarrier
 * @Date: 2021-03-09 11:03
 * @Version: 1.0
 *
 * 在CyclicBarrier类的内部有一个计数器，每个线程在到达屏障点的时候都会调用await方法
 * 将自己阻塞,此时计数器会减1，当计数器减为0的时候所有因调用await方法而被阻塞的线程将被唤醒。
 *
 * 被直接打断的线程抛InterruptedException;
 * 其余的线程抛因为打翻栅栏操作而被唤醒则抛出异常:BrokenBarrierException
 * 整盘游戏结束
 * cyclicBarrier.await() 1个api
 *
 */
public class UseCyclicBarrier02 {
    public static void main(String[] args) {

        ExecutorService executorService = Executors.newFixedThreadPool(2);

        CyclicBarrier cb = new CyclicBarrier(2, ()->{
            System.out.println("All has done");
        });

        for (int i = 0; i < 2; i++) {
            executorService.execute(()->{
                System.out.println("task1 begin");
                try {
                    Thread.sleep(300);
                    cb.await(); // blocked
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                } catch (BrokenBarrierException e) {
                    throw new RuntimeException(e);
                }
            });

            executorService.execute(()->{
                System.out.println("task2 begin");
                try {
                    Thread.sleep(3000);
                    cb.await();  // blocked
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                } catch (BrokenBarrierException e) {
                    throw new RuntimeException(e);
                }
            });
        }

        executorService.shutdown();


    }


}